From: Florian Müllner Date: Wed, 3 Aug 2022 00:58:21 +0000 (+0200) Subject: status/network: Add NMSection:icon-name property X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~461^2^2~50 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=f96447079a5056969d58e10b664b16b40fb236b7;p=gnome-shell.git status/network: Add NMSection:icon-name property Again no big surprise, a property that will soon correspond to the quick toggle's icon. It is more involved than the :checked property though, which is just a simple boolean. To keep it as simple as possible, we set up a binding group and use that to bind the :icon-name property. As state changes, we then update the group's source with the item we deem to best represent the section as a whole at the given moment. That is (in that order): - the first active item - the most recently used item - the top-most visible item Part-of: --- diff --git a/js/ui/status/network.js b/js/ui/status/network.js index 20b44da1c..d382fed8e 100644 --- a/js/ui/status/network.js +++ b/js/ui/status/network.js @@ -1279,10 +1279,12 @@ const NMSection = GObject.registerClass({ 'checked': GObject.ParamSpec.boolean('checked', '', '', GObject.ParamFlags.READWRITE, false), + 'icon-name': GObject.ParamSpec.string('icon-name', '', '', + GObject.ParamFlags.READWRITE, + ''), }, Signals: { 'activation-failed': {}, - 'icon-changed': {}, }, }, class NMSection extends GObject.Object { constructor() { @@ -1297,6 +1299,10 @@ const NMSection = GObject.registerClass({ this.menu.addMenuItem(this._itemsSection); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + + this._itemBinding = new GObject.BindingGroup(); + this._itemBinding.bind('icon-name', + this, 'icon-name', GObject.BindingFlags.DEFAULT); } setClient(client) { @@ -1342,7 +1348,7 @@ const NMSection = GObject.registerClass({ `${this} already has an item for ${key}`); item.connectObject( - 'notify::is-active', () => this._updateChecked(), + 'notify::is-active', () => this._sync(), 'notify::name', () => this._resortItem(item), 'destroy', () => this._removeItem(key), this); @@ -1365,10 +1371,41 @@ const NMSection = GObject.registerClass({ this._sync(); } + *_getActiveItems() { + for (const item of this._itemSorter) { + if (item.is_active) + yield item; + } + } + + _getPrimaryItem() { + // prefer active items + const [firstActive] = this._getActiveItems(); + if (firstActive) + return firstActive; + + // otherwise prefer the most-recently used + const [lastUsed] = this._itemSorter.itemsByMru(); + if (lastUsed?.timestamp > 0) + return lastUsed; + + // as a last resort, return the top-most visible item + for (const item of this._itemSorter) { + if (item.visible) + return item; + } + + console.assert(!this.visible, + `${this} should not be visible when empty`); + + return null; + } + _sync() { this.visible = this._items.size > 0; this._updateItemsVisibility(); this._updateChecked(); + this._itemBinding.source = this._getPrimaryItem(); } }); @@ -1702,7 +1739,7 @@ class Indicator extends PanelMenu.SystemIndicator { this._allSections.forEach(section => { section.connectObject( 'activation-failed', () => this._onActivationFailed(), - 'icon-changed', () => this._updateIcon(), + 'notify::icon-name', () => this._updateIcon(), this); this.menu.addMenuItem(section.menu); });